class MVVM {
  constructor({ el, data, methods }) {
    this.el = document.querySelector(el);
    // console.log(this.el);
    // this._data = data;//defineProperty
    this.data = data;//Proxy
    this.domPool = {};
    this.methods = methods;
    this.init();
  }
  init () {
    this.initMethods();
    this.initData();
    this.initDom();
  }

  initMethods () {
    // console.log(this.methods);
    this.methods && Object.keys(this.methods).forEach(key => {
      // console.log(this[key]);
      this[key] || (this[key] = this.methods[key]);
    })
  }

  initData () {
    const _this = this;
    // this.data = {};
    // for (let key in this._data) {
    //   Object.defineProperty(this.data, key, {
    //     get () {
    //       // console.log('获取数据：', key, _this._data[key]);
    //       return _this._data[key];
    //     },
    //     set (newValue) {
    //       // console.log('设置数据：', key, newValue);
    //       // console.log(_this.domPool[key]);
    //       _this.domPool[key].innerHTML = newValue;
    //       _this._data[key] = newValue;
    //     }
    //   })
    // }

    this.data = new Proxy(this.data, {
      get (target, key) {
        // console.log(target, key);
        return Reflect.get(target, key)
      },
      set (target, key, value) {
        _this.domPool[key].innerHTML = value;
        return Reflect.set(target, key, value)
      }
    })
    // console.log(this.data['age']);
    // this.data['name'] = '哈哈哈哈';
  }

  initDom () {
    this.bindDom(this.el);
    this.bindInput(this.el);
    this.bindEvent(this.el);
  }

  bindDom (el) {
    const childNodes = el.childNodes;
    // console.log(el);
    // console.log(childNodes);
    childNodes.forEach(item => {
      // console.log(item.nodeType);
      if (item.nodeType === 3) {
        
      // console.log(item);
        const _value = item.nodeValue;
        if (_value.trim().length) {
          // console.log(_value.match(/\{\{(.+?)\}\}/))
          let _isValue = /\{\{(.+?)\}\}/.test(_value);
          // console.log(_isValue)
          if (_isValue) {
            const _key = _value.match(/\{\{(.+?)\}\}/)[1].trim();
            // console.log(_value.match(/\{\{(.+?)\}\}/)[1]);
            this.domPool[_key] = item.parentNode;
            // console.log(this.domPool[_key]);
            item.parentNode.innerText = this.data[_key] || undefined;
          }
        }
      }
      item.childNodes && this.bindDom(item);
    })
  }
  bindInput (el) {
    const _allInputs = el.querySelectorAll('input');
    _allInputs.forEach(input => {
      const _vModel = input.getAttribute('v-model');
      if (_vModel) {
        input.addEventListener('keyup', this.handleInput.bind(this, _vModel, input), false);
      }
    })
  }

  bindEvent (el) {
    const allItem = [...el.getElementsByTagName('*')];
    // console.log(allItem);
    const _this = this;
    allItem.forEach(item => {
      const eventKey = item.getAttributeNames();
      // console.log(eventKey);
      // [0:'@click']
      eventKey.forEach(key => {
        // console.log(key);
        if (/^@[a-z]+/.test(key)) {
          const _item = item.getAttribute(key);
          const _itemKey = key.replace('@', '');
          // console.log(_itemKey)
          if (_item) {
            item.addEventListener(_itemKey, (event) => {
              this[_item].call(_this, event)
            }, false);
          }
        }
      })

    })
  }

  handleInput (key, input) {
    const _value = input.value;
    this.data[key] = _value;
  }

  setData (key, value) {
    this.data[key] = value;
  }
}